package com.jc.ds.base.service;

import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.jc.common.util.CamelCaseUtils;
import com.jc.common.util.CommonStr;
import com.jc.common.util.MapUtils;
import com.jc.ds.mapper.BaseCustomMapper;
import com.jc.ds.mapper.BaseMapper;

public abstract class BaseServiceImpl<T, E, K> implements BaseService<T, K> {
	private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());

	public Logger getLOGGER() {
		return LOGGER;
	}

	@Autowired
	private BaseMapper<T, K>		baseMapper;
	@Autowired
	private BaseCustomMapper<E, K>	baseCustomMapper;

	/** 通用mapper */
	public BaseMapper<T, K> getBaseMapper() {
		return baseMapper;
	}

	/** 获取自定义通用mapper */
	public BaseCustomMapper<E, K> getBaseCustomMapper() {
		return baseCustomMapper;
	}

	/** 获取自定义通用mapper */
	public <M> M getBaseCustomMapper(Class<M> clz) {
		return (M) baseCustomMapper;
	}

	/**
	 * 获取自定义mapper对象，需要自己实现 <br/>
	 * <font> 例：<br/>
	 * public <span style="color:red;">CMpermissionMapper</span> getCustomMapper() { <br/>
	 * &nbsp;&nbsp;&nbsp; return (CMpermissionMapper) this.getBaseCustomMapper();<br/>
	 * }</font>
	 */
	public abstract BaseCustomMapper<E, K> getCustomMapper();

	@Override
	@Transactional
	public int add(T bean, boolean isSaveNull) {
		if (bean == null) { throw new NullPointerException("保存数据为空"); }
		try {
			return isSaveNull ? this.getBaseMapper().insert(bean) : this.getBaseMapper().insertSelective(bean);
		} catch (DataIntegrityViolationException e) {
			getLOGGER().error("{}:{}-{}", JSONObject.toJSONString(bean), e.getLocalizedMessage(), e.getMessage());
			throw new BaseServiceException("数据不符合存储要求，请检查确认");
		}
	}

	@Override
	@Transactional
	public int remove(K id) {
		return this.getBaseMapper().deleteByPrimaryKey(id);
	}

	@Override
	@Transactional
	public int modify(T bean, boolean isSaveNull) {
		if (bean == null) { throw new NullPointerException("保存数据为空"); }
		try {
			return isSaveNull ? this.getBaseMapper().updateByPrimaryKey(bean) : this.getBaseMapper().updateByPrimaryKeySelective(bean);
		} catch (DataIntegrityViolationException e) {
			getLOGGER().error("{}:{}-{}", JSONObject.toJSONString(bean), e.getLocalizedMessage(), e.getMessage(), e);
			throw new BaseServiceException("数据不符合存储要求，请检查确认");
		}
	}

	@Override
	public T queryById(K id) {
		return this.getBaseMapper().selectByPrimaryKey(id);
	}

	@Override
	public List<T> queryAll(T bean) {
		return this.getBaseMapper().selectAll(bean);
	}

	@Override
	public List<T> queryAll(T bean, boolean isPage) {
		if (isPage) {
			PageHelper.startPage(bean);
		}
		return this.getBaseMapper().selectAll(bean);
	}

	@Override
	public int queryAllCount(T bean) {
		return this.getBaseMapper().selectAllCount(bean);
	}

	@Override
	public List<T> queryLikeAll(T bean) {
		return this.getBaseMapper().selectLikeAll(bean);
	}

	@Override
	public List<T> queryLikeAll(T bean, boolean isPage) {
		if (isPage) {
			PageHelper.startPage(bean);
		}
		return this.getBaseMapper().selectLikeAll(bean);
	}

	@Override
	public int queryLikeAllCount(T bean) {
		return this.getBaseMapper().selectLikeAllCount(bean);
	}

	protected void setOrderBy(Map<String, Object> parameterMap) {
		StringBuilder stringBuilder = new StringBuilder(" ORDER BY ");
		String sort = MapUtils.getString(parameterMap, "sort");
		if (org.apache.commons.lang3.StringUtils.isNotBlank(sort)) {
			String order = MapUtils.getString(parameterMap, "order");
			String[] _order = order.split(CommonStr.SPLIT_COMMA);
			String[] _sort = sort.split(CommonStr.SPLIT_COMMA);
			for (int i = 0; i < _sort.length; i++) {
				String string = _sort[i];
				if (StringUtils.isNotBlank(string)) {
					if (i > 0) {
						stringBuilder.append(",");
					}
					stringBuilder.append(CamelCaseUtils.toUnderlineName(string)).append(" ");
					if (i < _order.length) {
						stringBuilder.append(_order[i]);
					} else {
						stringBuilder.append("asc");
					}
				}
			}
			parameterMap.put("orderStr", stringBuilder.toString());
		} else {
			parameterMap.put("orderStr", null);
		}
	}
}
